package work.jame.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import work.jame.blog.framework.exception.BusinessException;
import work.jame.blog.framework.exception.db.InsertDataBaseException;
import work.jame.blog.framework.utils.security.SpringSecurityUtils;
import work.jame.blog.pojo.UserArticleCollect;
import work.jame.blog.mapper.UserArticleCollectMapper;
import work.jame.blog.service.UserArticleCollectService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import work.jame.blog.service.UserCollectGroupService;

import javax.annotation.Resource;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Jame
 * @since 2023-05-18
 */
@Service
public class UserArticleCollectServiceImpl extends ServiceImpl<UserArticleCollectMapper, UserArticleCollect> implements UserArticleCollectService {


    @Autowired
    private UserCollectGroupService userCollectGroupService;

    @Resource
    private UserArticleCollectMapper userArticleCollectMapper;

    @Override
    public boolean deleteByGroupId(Long groupId) {
        QueryWrapper<UserArticleCollect> wrapper = new QueryWrapper<>();
        wrapper.eq("group_id", groupId);
        return this.remove(wrapper);
    }

    @Override
    public boolean saveUserArticleCollect(UserArticleCollect userArticleCollect) {
        Long userId = SpringSecurityUtils.getCurrentLoginUserId();
        userArticleCollect.setUserId(userId);
        if (!userCollectGroupService.queryGroupCreateUser(userArticleCollect.getGroupId(), userId)) {
            throw new BusinessException("不能将文章保存到不是自己的分组中");
        }
        return this.save(userArticleCollect);
    }

    @Override
    public boolean delete(Long groupId, Long articleId) {
        Long userId = SpringSecurityUtils.getCurrentLoginUserId();
        QueryWrapper<UserArticleCollect> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId)
                .eq("article_id", articleId)
                .eq("group_id", groupId);
        return this.remove(wrapper);
    }

    @Override
    @Transactional
    public void update(List<UserArticleCollect> articleCollects) {
        if (articleCollects.isEmpty()) {
            throw new BusinessException("更新内容为空");
        }
        Long articleId = null;
        Long userId = SpringSecurityUtils.getCurrentLoginUserId();
        for (UserArticleCollect articleCollect : articleCollects) {
            articleCollect.setUserId(userId);
            if (Objects.isNull(articleId)) {
                articleId = articleCollect.getArticleId();
            } else if (!articleId.equals(articleCollect.getArticleId())) {
                throw new BusinessException("只能同时修改一个文章所在分组");
            }
        }

        QueryWrapper<UserArticleCollect> wrapper = new QueryWrapper<>();
        wrapper.eq("article_id", articleId)
                .eq("user_id", userId);
        List<UserArticleCollect> dbCollects = this.list(wrapper);
        //如果从来没有收藏过这篇文章,则直接保存
        if (dbCollects.isEmpty()) {
            if (!this.saveBatch(articleCollects)) {
                throw new InsertDataBaseException("更新收藏失败");
            }
            return;
        }

        //需要保存的集合
        ArrayList<UserArticleCollect> saveCollects = new ArrayList<>();
        //需要删除的集合
        ArrayList<UserArticleCollect> deleteCollects = new ArrayList<>();

        ArrayList<UserArticleCollect> list = new ArrayList<>(dbCollects);

        //取两个集合互相的差集
        for (UserArticleCollect dbCollect : dbCollects) {
            boolean exist = false;
            for (UserArticleCollect articleCollect : articleCollects) {
                if (articleCollect.getGroupId().equals(dbCollect.getGroupId()) &&
                        articleCollect.getArticleId().equals(dbCollect.getArticleId())) {
                    exist = true;
                    break;
                }
            }
            if (!exist) {
                deleteCollects.add(dbCollect);
                list.add(dbCollect);
            }
        }
        for (UserArticleCollect articleCollect : articleCollects) {
            boolean exist = false;
            for (UserArticleCollect userArticleCollect : list) {
                if (articleCollect.getGroupId().equals(userArticleCollect.getGroupId()) &&
                        articleCollect.getArticleId().equals(userArticleCollect.getArticleId())) {
                    exist = true;
                    break;
                }
            }
            if (!exist) {
                saveCollects.add(articleCollect);
            }
        }

        if (!saveCollects.isEmpty() && !this.saveBatch(saveCollects)) {
            throw new InsertDataBaseException("更新收藏失败");
        }
        if (!deleteCollects.isEmpty() && !this.removeBatchByIds(deleteCollects)) {
            throw new InsertDataBaseException("更新收藏失败");
        }
    }

    @Override
    public boolean removeAllCollectByArticleId(Long articleId) {
        Long userId = SpringSecurityUtils.getCurrentLoginUserId();
        QueryWrapper<UserArticleCollect> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId)
                .eq("article_id",articleId);
        return this.remove(wrapper);
    }

}
